package com.mars.module.system.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mars.common.response.PageInfo;
import com.mars.common.request.sys.SysMenuQueryRequest;
import com.mars.common.request.sys.SysMenuAddRequest;
import com.mars.common.request.sys.SysMenuUpdateRequest;
import com.mars.common.response.sys.SysParentMenuResponse;
import com.mars.framework.exception.ServiceException;
import com.mars.module.system.mapper.SysMenuMapper;
import com.mars.module.system.mapper.SysUserMapper;
import com.mars.module.system.entity.SysMenu;
import com.mars.common.util.IdUtils;
import com.mars.common.response.sys.SysMenuResponse;
import com.mars.module.system.service.ISysMenuService;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 菜单Service
 *
 * @author 源码字节-程序员Mars
 */
@Service
@AllArgsConstructor
public class SysMenuServiceImpl implements ISysMenuService {

    private final SysMenuMapper sysMenuMapper;

    @Override
    public List<SysMenuResponse> tree(SysMenuQueryRequest queryDto) {
        List<SysMenu> list = sysMenuMapper.selectByCondition(queryDto);
        list.sort(Comparator.comparing(SysMenu::getSort));
        List<SysMenuResponse> voList = new ArrayList<>();
        for (SysMenu sysMenu : list) {
            SysMenuResponse sysMenuVo = new SysMenuResponse();
            if (sysMenu.getParentId().equals(0L)) {
                BeanUtils.copyProperties(sysMenu, sysMenuVo);
                sysMenuVo.setChildren(getChildren(list, sysMenu.getId()));
                voList.add(sysMenuVo);
            }
        }
        return voList;
    }

    @Override
    public PageInfo<SysMenuResponse> list(SysMenuQueryRequest queryDto) {
        IPage<SysMenuResponse> page = sysMenuMapper.selectPageList(queryDto.page(), queryDto).convert(x -> {
            SysMenuResponse vo = new SysMenuResponse();
            BeanUtils.copyProperties(x, vo);
            return vo;
        });
        return PageInfo.build(page);
    }

    @Override
    public List<SysMenuResponse> getChildren(List<SysMenu> list, Long id) {
        List<SysMenuResponse> voList = new ArrayList<>();
        for (SysMenu sysMenu : list) {
            SysMenuResponse sysMenuVo = new SysMenuResponse();
            if (sysMenu.getParentId() != null && sysMenu.getParentId().equals(id)) {
                BeanUtils.copyProperties(sysMenu, sysMenuVo);
                sysMenuVo.setChildren(getChildren(list, sysMenu.getId()));
                voList.add(sysMenuVo);
            }
        }
        return voList;
    }

    @Override
    public SysMenuResponse get(Long id) {
        SysMenu sysMenu = sysMenuMapper.selectById(id);
        if (Objects.isNull(sysMenu)) {
            throw new ServiceException("数据不存在");
        }
        SysMenuResponse sysMenuVo = new SysMenuResponse();
        BeanUtils.copyProperties(sysMenu, sysMenuVo);
        return sysMenuVo;
    }

    @Override
    public List<SysMenuResponse> selectByUserId(Long userId) {
        List<SysMenu> list = sysMenuMapper.selectByUserId(userId);
        list.sort(Comparator.comparing(SysMenu::getSort));
        List<SysMenuResponse> voList = new ArrayList<>();
        for (SysMenu sysMenu : list) {
            SysMenuResponse sysMenuVo = new SysMenuResponse();
            if (sysMenu.getParentId().equals(0L)) {
                BeanUtils.copyProperties(sysMenu, sysMenuVo);
                sysMenuVo.setChildren(getChildren(list, sysMenu.getId()));
                voList.add(sysMenuVo);
            }
        }
        return voList;
    }

    @Override
    public void add(SysMenuAddRequest addDto) {
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(addDto, sysMenu);
        sysMenu.setParentId(addDto.getParentId() == null ? 0L : addDto.getParentId());
        sysMenu.setSort(addDto.getSort() == null ? 0 : addDto.getSort());
        sysMenuMapper.insert(sysMenu);
    }

    @Override
    public void update(SysMenuUpdateRequest updateDto) {
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(updateDto, sysMenu);
        sysMenu.setParentId(updateDto.getParentId() == null ? 0L : updateDto.getParentId());
        sysMenu.setSort(updateDto.getSort() == null ? 0 : updateDto.getSort());
        sysMenuMapper.updateById(sysMenu);
    }

    @Override
    public void delete(Long id) {
        sysMenuMapper.deleteById(id);
    }

    @Override
    public List<SysParentMenuResponse> getParentMenu() {
        return sysMenuMapper.selectList(Wrappers.lambdaQuery(SysMenu.class)
                .eq(SysMenu::getParentId, 0).orderByAsc(SysMenu::getSort)).stream().map(x -> {
            SysParentMenuResponse response = new SysParentMenuResponse();
            BeanUtils.copyProperties(x, response);
            return response;
        }).collect(Collectors.toList());
    }
}
